﻿using System;
using System.IO;
using System.Linq;
using System.Threading;
using FFmpegVideoClip.Lib.AdvancedFragmentProcessor;

namespace FFmpegVideoClip.Lib.Afterprocessings
{
    internal class AfterprocessingOperates
    {
        private static int FragmentID = 10000;
        public AfterprocessingTaskFlow[] taskFlows { get; private set; }
        private Clip m_clip;
        private AdvancedParametersSchemeModule[] modules;
        private int CurrentFragmentID;
        public CancellationTokenSource cancellationTokenSource = new();
        public bool IsCancellationRequested => Tools.IsCancellationRequested || cancellationTokenSource.IsCancellationRequested;

        public AfterprocessingOperates(Clip clip)
        {
            m_clip = clip;
            modules = clip.AfterprocessingFlows.Select(p => p.DeepCopy()).ToArray();
            taskFlows = new AfterprocessingTaskFlow[modules.Length];
            CurrentFragmentID = FragmentID++;

            for (int i = 0; i < modules.Length; i++)
            {
                try { taskFlows[i] = new AfterprocessingTaskFlow(m_clip, modules, CurrentFragmentID, i); }
                catch (Exception e)
                {
                    AfterprocessingOperatesException exc = new AfterprocessingOperatesException($"后处理初始化错误:[{m_clip.Name}]->{modules[i].SchemeName}", e);
                    LogManage.WriteExceptionInfo("后处理错误:", exc, true);
                    throw exc;
                }
            }
        }

        public void Execute(string StandardFlowsFinalResultFilePath)
        {
            if (!File.Exists(StandardFlowsFinalResultFilePath))
            {
                FileNotFoundException exception = new FileNotFoundException($"后处理初始化错误：标准处理生成的文件 [{Path.GetFileName(StandardFlowsFinalResultFilePath)}] 不存在,完整路径：[{StandardFlowsFinalResultFilePath}]");
                LogManage.WriteExceptionInfo("后处理错误:", exception, true);
                throw exception;
            }
            foreach (AfterprocessingTaskFlow current in taskFlows)
            {
                if (IsCancellationRequested)
                    return;
                try
                {
                    current.Init(StandardFlowsFinalResultFilePath);
                    current.Execute();
                }
                catch (Exception e)
                {
                    AfterprocessingOperatesException exc = new AfterprocessingOperatesException($"后处理执行错误:[{m_clip.Name}]->{current.Name}", e);
                    LogManage.WriteExceptionInfo("后处理错误:", exc, true);
                    throw exc;
                }
            }
        }

        public void Cancel()
        {
            cancellationTokenSource.Cancel();
            foreach (AfterprocessingTaskFlow item in taskFlows)
                item.Cancel();
        }

        [Serializable]
        public class AfterprocessingOperatesException : Exception
        {
            public AfterprocessingOperatesException() { }
            public AfterprocessingOperatesException(string message) : base(message) { }
            public AfterprocessingOperatesException(string message, Exception inner) : base(message, inner) { }
            [Obsolete]protected AfterprocessingOperatesException(
              System.Runtime.Serialization.SerializationInfo info,
              System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
        }
    }
}
